#include "card_emu.h"
#include <stdio.h>
#include "user_config.h"
#include "sys_init.h"
#include "dk_account_manager.h"

#define CARRIER_IN(...)            //GPIO_SetBits(LED_WHITE_GPIOx, LED_WHITE)
#define CARRIER_OUT(...)          // GPIO_ResetBits(LED_WHITE_GPIOx, LED_WHITE)

#define CARD_ACTIVE(...)          // GPIO_SetBits(LED_BLUE_GPIOx, LED_BLUE)
#define CARD_INACTIVE(...)        // GPIO_ResetBits(LED_BLUE_GPIOx, LED_BLUE)

#define CARD_TRANSMIT(...)          // GPIO_SetBits(LED_RED_GPIOx, LED_RED)
#define CARD_TRANSMIT_DONE(...)     // GPIO_ResetBits(LED_RED_GPIOx, LED_RED)

#if 0
uint8_t t2t_mem[][4] =
{
    {0x53,0x40,0xE3,0x78},
    {0x2F,0x21,0x00,0x01},
    {0x0F,0x48,0x00,0x00},
    {0xE1,0x10,0x12,0x00},
    {0x01,0x03,0xA0,0x0C},

    //网址信息
    {0x34,0x03,0x48,0x91},
    {0x01,0x24,0x55,0x00},
    {0x77,0x65,0x69,0x78},
    {0x69,0x6E,0x3A,0x2F},
    {0x2F,0x64,0x6C,0x2F},
    {0x62,0x75,0x73,0x69},

    {0x6E,0x65,0x73,0x73},

    {0x2F,0x3F,0x74,0x3D},
    {0x37,0x4D,0x64,0x6E},
    {0x4A,0x4C,0x76,0x57},
    {0x4A,0x61,0x76,0x54},
    {0x0F,0x0E,0x61,0x6E},
    {0x64,0x72,0x6F,0x69},
    {0x64,0x2E,0x63,0x6F},
    {0x6D,0x3A,0x70,0x6B},

    {0x67,0x63,0x6F,0x6D},
    {0x2E,0x74,0x65,0x6E},
    {0x63,0x65,0x6E,0x74},
    {0x2E,0x6D,0x6D,0xFE},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0xBD},
    {0x04,0x00,0x00,0xFF},
    {0x00,0x05,0x00,0x00},
    {0xFF,0xFF,0xFF,0xFF},
    {0x00,0x00,0x00,0x00},
};
#else
uint8_t t2t_mem1[256][4] =
{
    {0x04,0x8D,0xAA,0xAB},
    {0xD2,0xD2,0x64,0x80},
    {0xE4,0x48,0x00,0x00},
    {0xE1,0x11,0x12,0x00},
    {0x03,0x16,0xD1,0x01},
    //网址信息
    {0x12,0x55,0x01,0x6d},
    {0x65,0x67,0x61,0x68},
    {0x75,0x6e,0x74,0x6d},
    {0x69,0x63,0x72,0x6f},
    {0x2e,0x63,0x6f,0x6d},
    {0xfe,0x00,0x00,0x00},

    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0xBD},
    {0x04,0x00,0x00,0xFF},
    {0x00,0x05,0x00,0x00},
    {0xFF,0xFF,0xFF,0xFF},
    {0x00,0x00,0x00,0x00},
};
#endif

uint8_t t2t_mem[][4] =
{
    {0xAC,0xDC,0x2A,0x7A},
    {0x6A,0x64,0x34,0x80},
    {0xBA,0x00,0x00,0x00},
    {0xE1,0x10,0x6d,0x00}, //cc 字节 byte3 :NTAG213的CC Byte2值为12h，NTAG215为3Eh，NTAG216为6Dh。这些值对应不同的用户存储器容量：NTAG213为144字节，NTAG215为504字节（表格中写496字节但应为504字节），NTAG216为888字节（表格中写872字节但应为888字节）
    {0x01,0x03,0xA0,0x0C},
    {0x34,0x03,0x48,0x91},//第三个字节为总长度
    {0x01,0x24,0x55,0x00},//第一个字节0x01为类型长度，第二个字节为内容长度包含0xFE
    {0x77,0x65,0x69,0x78},
    {0x69,0x6E,0x3A,0x2F},
    {0x2F,0x64,0x6C,0x2F},
    {0x62,0x75,0x73,0x69},
    {0x6E,0x65,0x73,0x73},
    {0x2F,0x3F,0x74,0x3D},
    {0x34,0x41,0x46,0x57},
    {0x56,0x31,0x31,0x77},
    {0x43,0x42,0x64,0x54},
    {0x0F,0x0E,0x61,0x6E},
    {0x64,0x72,0x6F,0x69},
    {0x64,0x2E,0x63,0x6F},
    {0x6D,0x3A,0x70,0x6B},
    {0x67,0x63,0x6F,0x6D},
    {0x2E,0x74,0x65,0x6E},
    {0x63,0x65,0x6E,0x74},
    {0x2E,0x6D,0x6D,0xFE},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0x00},
    {0x00,0x00,0x00,0xBD},
    {0x04,0x00,0x00,0xFF},
    {0x00,0x05,0x00,0x00},
    {0xFF,0xFF,0xFF,0xFF},
    {0x00,0x00,0x00,0x00},

};

uint8_t t2t_ver[8] = {0x00,0x04,0x04,0x02,0x01,0x00,0x13,0x03};

uint8_t t2t_ecc[32] = {0x96,0xF3,0x0D,0x59,0xA1,0x28,0x6E,0xD0,0x22,0x5F,0xEE,0x46,0xBB,0x75,0x31,0x3D,\
                       0x79,0x70,0x3D,0xD7,0x0C,0x1D,0xF6,0x11,0x12,0x9F,0xBF,0xA3,0xCF,0x52,0x8C,0xAD
                      };
t4t_entity t4t_tag = {0};

hal_nfc_regval_t picc_configs[] =
{
  {0, 0x01, 0x00},
  {0, 0x02, 0x00},
  {0, 0x03, 0x80},
  {1, 0x12, 0x80},
  {1, 0x13, 0x80},
  {1, 0x14, 0x00},//关闭发射
  {2, 0x28, 0x01},//设置发射能量
  {7, 0x32, 0x70},
  {8, 0x3b, 0x01},//mag detect enable
  {9, 0x3a, 0x6d},//picc config,except picc enable
  //{9, 0x3b, 0x77},//设置rxdata解调上下限
  {9, 0x3b, 0x00},//设置rxdata解调上下限
  {9, 0x3d, 0xf0},//设置rx增益
  {9, 0x3e, 0xb3},//选择解调方案
  {10, 0x3a, 0x00},
};

const uint16_t au16FSD_CODE[] = {16,24,32,40,48,64,96,128,256};

struct picc_config_t picc_conf =
{
    .uid = {0xAC, 0xDC, 0x2A, 0x6A, 0x64, 0x34, 0x80},
    .coll_level = 2,
    .enable_14443_4 = 0,
    .atqa = 0x0044,
      .ats =
      {
        .TL = sizeof(struct picc_ats),
        .T0 = 0x75,
        .TA = 0x77,
        .TB = 0x81,
        .TC = 0x02,
      },
};

struct picc_run_t picc_run =
{
    .en = 1,
};

void picc_run_state(picc_state_e state)
{
    picc_run.state = state;
}

static uint8_t picc_run_state_check(picc_state_e state)
{
    return (picc_run.state == state);
}

void picc_reset(void)
{
    hal_nfc_bit_set(9, 0x3a, 0x80, 1);//reset picc
}

void picc_uid_set(uint8_t *uid, uint8_t len)
{
    hal_nfc_set_register(9, 0x31, uid[0], 1);
    for(uint8_t i = 1; i < 4; i++)
        hal_nfc_set_register(9, 0x31+i, uid[i], 0);
    if(len == 7)
    {
        hal_nfc_set_register(9, 0x35, uid[4], 0);
        hal_nfc_set_register(9, 0x36, uid[5], 0);
        hal_nfc_set_register(9, 0x38, uid[6], 0);
        hal_nfc_bit_set(9, 0x39, 1, 0);
    }
}

static void picc_set_atqa_hbyte(uint8_t atqa_h)
{
    hal_nfc_set_register(8, 0x35, atqa_h, 1);
}

static void picc_set_atqa_lbyte(uint8_t atqa_l)
{
    //only bit[6:0] can be set
    hal_nfc_set_register(8, 0x36, atqa_l & 0x3f, 1);
}

void picc_set_rate(uint8_t rate)
{
    rate = rate & 0x3;
    picc_run.rate = rate;
    switch(rate)
    {
    case 0:
        pcd_set_rate('1', 'A');
        break;
    case 1:
        pcd_set_rate('2', 'A');
        break;
    case 2:
        pcd_set_rate('4', 'A');
        break;
    case 3:
        pcd_set_rate('8', 'A');
        break;
    }
}

uint8_t picc_get_rate(void)
{
    return picc_run.rate;
}

static uint16_t picc_get_rx_len(void)
{
    return hal_nfc_get_register(0, 0x0a, 1);
}

static uint8_t picc_get_err(void)
{
    return hal_nfc_get_register(0, 0x06, 1);
}

static void picc_set_halt(void)
{
  hal_nfc_bit_set(8, 0x3e, 0x08, 1);
    picc_run_state(PICC_STATE_HALT);
}

static void picc_set_idle(void)
{
  hal_nfc_bit_set(8, 0x3e, 0x10, 1);
    picc_run_state(PICC_STATE_IDLE);
}

static void picc_event_register(intc_event_e e, picc_event cb)
{
    picc_conf.event[e] = cb;
}

static void picc_event_unregister(intc_event_e e)
{
    picc_conf.event[e] = NULL;
}

static uint32_t picc_get_event(void)
{
    uint32_t event = 0;
    event = ((hal_nfc_get_register(8, 0x3e, 1) >> 6) << PICC_ACTIVE_EVENT);
    event |= ((hal_nfc_get_register(8, 0x3b, 0) >> 6) << PICC_FIELD_IN_EVENT);
    event |= hal_nfc_get_register(0, 0x4, 0);
    hal_nfc_set_register(0, 0x04, 0x7f, 0);
    return event;
}

//进场处理
static void picc_field_in_callback(uint32_t event)
{
    CARRIER_IN();
    //进场不进行触摸检测

//    if(gt_sys_val.sys_cfg.pcd_picc_mode == MODE_PCD_PICC_COEXIST){
//       // g_u16timer_delay[AUTO_SEARCH_DELAY] = gt_sys_val.sys_cfg.u16Auto_search_card_delay;
//        g_u16timer_delay[AUTO_SEARCH_DELAY] = gt_sys_val.sys_cfg.u16Picc_remain_delay;
//    }
}

//离场处理
static void picc_field_out_callback(uint32_t event)
{
  if(GPIO_ReadPortPin(READER_IRQ_PORT, READER_IRQ_Pin ))
  {
    //mh1612s_card_emu_optimize_out_carrier_callback(opt_hw);
  }
    CARRIER_OUT();
}

//使能picc进场中断
static void picc_field_in_irq(uint8_t en)
{
  if(en)
  {
    hal_nfc_bit_set(8, 0x3b, 0x04, 1);
    picc_event_register(PICC_FIELD_IN_EVENT, picc_field_in_callback);
  }
  else
  {
    hal_nfc_bit_clear(8, 0x3b, 0x04, 1);
    picc_event_unregister(PICC_FIELD_IN_EVENT);
  }
}

//使能picc离场中断
static void picc_field_out_irq(uint8_t en)
{
  if(en)
  {
    hal_nfc_bit_set(8, 0x3b, 0x08, 1);
    picc_event_register(PICC_FIELD_OUT_EVENT, picc_field_out_callback);
  }
  else
  {
    hal_nfc_bit_clear(8, 0x3b, 0x08, 1);
    picc_event_unregister(PICC_FIELD_OUT_EVENT);
  }
}

static void picc_active_callback(uint32_t event)
{
  CARD_ACTIVE();
    picc_run_state(PICC_STATE_ACTIVE);
}

static void picc_inactive_callback(uint32_t event)
{
    CARD_INACTIVE();
    if(picc_get_rate())
    {
        picc_set_rate(0);
    }
    picc_run_state(PICC_STATE_IDLE);
}

static void picc_active_irq(uint8_t en)
{
  if(en)
  {
    hal_nfc_bit_set(8, 0x3e, 0x20, 1);
    picc_event_register(PICC_ACTIVE_EVENT, picc_active_callback);
    picc_event_register(PICC_INACTIVE_EVENT, picc_inactive_callback);
  }
  else
  {
    hal_nfc_bit_clear(8, 0x3e, 0x20, 1);
    picc_event_unregister(PICC_ACTIVE_EVENT);
    picc_event_unregister(PICC_INACTIVE_EVENT);
  }
}

static void picc_err_callback(uint32_t event)
{
  printf("err:%x\n", picc_get_err());
    picc_set_idle();
}

void picc_write(uint8_t *buf, uint16_t len)
{
    hal_nfc_bit_clear(8, 0x3e, 0x20, 1);
  hal_nfc_bit_set(9, 0x3a, 0x80, 1);
  CARD_TRANSMIT();
//  printf("PICC Send data:%d\r\n", len);
//  for(int i = 0;i < len;i++)
//      printf("%02x ", buf[i]);
//  printf("\r\n");

  for (uint16_t j = 0; j < len; j++)
  {
      hal_nfc_write_register(REG_FIFODATA, buf[j]);
  }
  //transmit command
  hal_nfc_set_register(0, 0x1, 4, 0);
  while(!hal_nfc_bit_check(0, 0x04, PICC_TxIrq, 0) && (hal_nfc_bit_check(8, 0x3e, 6, 1)));
  hal_nfc_bit_set(0, 0x04, PICC_TxIrq, 0);
    hal_nfc_bit_set(8, 0x3e, 0x20, 1);
  CARD_TRANSMIT_DONE();
}

static void picc_t2t_ack(void)
{
    hal_nfc_bit_set(9, 0x39, 0x04, 1);//open halt byte send
    picc_write("\x0A", 1);
    hal_nfc_bit_clear(9, 0x39, 0x04, 1);//close halt byte send
}

static void picc_t2t_nak(uint8_t err)
{
    hal_nfc_bit_set(9, 0x39, 0x04, 1);//open halt byte send
    picc_write(&err, 1);
    hal_nfc_bit_clear(9, 0x39, 0x04, 1);//close halt byte send
}

static void picc_t2t_process(void)
{
  switch (picc_run.rx_buf[0])
  {
        case 0x50:
        picc_set_halt();
        break;
        case 0x30:
        picc_write(t2t_mem[picc_run.rx_buf[1]], 16);
        break;
        case 0x60:
        picc_write(t2t_ver, 8);
        break;
        case 0x3C:
        picc_write(t2t_ecc, 32);
        break;
        case 0x3A:
        picc_write(t2t_mem[picc_run.rx_buf[1]], (picc_run.rx_buf[2] - picc_run.rx_buf[1] + 1)*4);
        break;
        case 0x1b:
        picc_write("\x00\x00", 2);
        break;
        case 0xA2:
            memcpy(t2t_mem[picc_run.rx_buf[1]], &picc_run.rx_buf[2], 4);
            picc_t2t_ack();
        break;
        default:
            break;
  }
}

void picc_blk_num_set(uint8_t num)
{
  picc_run.local_blk_num = num;
}

uint8_t picc_blk_num_get(void)
{
  return picc_run.local_blk_num;
}

uint8_t picc_check_cid(uint8_t cid)
{
  return (cid == picc_run.rats.cid);
}

uint8_t picc_cid_get(void)
{
  return picc_run.rats.cid;
}

void picc_cid_set(uint8_t cid)
{
  picc_run.rats.cid = cid;
}

static void picc_t4t_deselect(block_prologue_field_t* p)
{
    uint8_t len = 0;
    //PCB
    picc_run.tx_buf[len++] = p->PCB.val;
    //cid
    if(p->PCB.val & BIT3)
        picc_run.tx_buf[len++] = p->cid;

  picc_run.tx_len = len;

    picc_write(picc_run.tx_buf, picc_run.tx_len);
    picc_set_halt();
    pcd_set_rate('1', 'A');
}

void picc_t4t_send_i(block_prologue_field_t* p, r_apdu_t *r)
{
    uint8_t len = 0;
    //PCB
    picc_run.tx_buf[len++] = p->PCB.val;
    //cid
    if(p->PCB.val & BIT3)
        picc_run.tx_buf[len++] = p->cid;
    //inf
    if(r->len)
    {
        memcpy(&picc_run.tx_buf[len], r->data, r->len);
        len += r->len;
    }
    //sw
    picc_run.tx_buf[len++] = (uint8_t)(r->sw >> 8);
    picc_run.tx_buf[len++] = (uint8_t)(r->sw & 0xff);
  picc_run.tx_len = len;

    picc_write(picc_run.tx_buf, picc_run.tx_len);

    picc_blk_num_set(p->PCB.val & BIT0);
}

void picc_t4t_send_r(block_prologue_field_t* p)
{
    uint8_t len = 0;
    //PCB
    picc_run.tx_buf[len++] = p->PCB.val;
    //cid
    if(p->PCB.val & BIT3)
        picc_run.tx_buf[len++] = p->cid;

    picc_run.tx_len = len;
    picc_write(picc_run.tx_buf, picc_run.tx_len);

    picc_blk_num_set(p->PCB.val & BIT0);
}

//block process
/*
return
-1:err
0:i
1:r
2:wtx
3:pps
4:deselect
*/
block_preprocess_t picc_t4t_block_process(uint8_t *rx_buf, uint16_t rx_len)
{
  block_prologue_field_t* rx_prologue = (block_prologue_field_t*)rx_buf;
  block_preprocess_t b_pr = {0};

    if((rx_prologue->PCB.val & BIT3) == BIT3)
    {
        if(!picc_check_cid(rx_prologue->cid))
        {
            b_pr.valid = 2;//cid err
            return b_pr;
        }
        b_pr.prologue.PCB.val |= BIT3;
        b_pr.prologue.cid = rx_prologue->cid;
    }

  switch(rx_prologue->PCB.val >> 6)
  {
    case 0://i block
            if((rx_prologue->PCB.val & PCD_CMD_I_BLOCK_Msk) != PCD_CMD_I_BLOCK)
            {
                b_pr.valid = 3;//i_pcb err
                return b_pr;
            }
      if(rx_prologue->PCB.i_pcb.chain_flg)
      {//R(ACK)

      }
      else
      {
                b_pr.valid = 1;
        b_pr.prologue.PCB.i_pcb.blk_t = 0;
        b_pr.prologue.PCB.i_pcb.fixed1 = 1;
        b_pr.prologue.PCB.i_pcb.blk_num = rx_prologue->PCB.i_pcb.blk_num;
                b_pr.data = &rx_buf[1+rx_prologue->PCB.i_pcb.cid_flw + rx_prologue->PCB.i_pcb.nad_flw];
                b_pr.data_len = rx_len - 1 -rx_prologue->PCB.i_pcb.cid_flw - rx_prologue->PCB.i_pcb.nad_flw;
      }
      break;
    case 2://r block
      if((rx_prologue->PCB.val & PCD_CMD_R_BLOCK_Msk) != PCD_CMD_R_BLOCK)
      {
                b_pr.valid = 4;//r_pcb err
                return b_pr;
      }
            b_pr.valid = 1;
      if(rx_prologue->PCB.r_pcb.blk_num == picc_blk_num_get())
      {
                //block number match,send last i block
            }
            else
            {
                if(rx_prologue->PCB.r_pcb.nak_flg)
                {
                    b_pr.prologue.PCB.r_pcb.blk_t = 2;
                    b_pr.prologue.PCB.r_pcb.fixed0 = 0;
                    b_pr.prologue.PCB.r_pcb.fixed1 = b_pr.prologue.PCB.r_pcb.fixed1_ = 1;
                    b_pr.prologue.PCB.r_pcb.blk_num = picc_blk_num_get();
                    b_pr.prologue.PCB.r_pcb.nak_flg = 0;
                }
            }
      break;
    case 3://s block
      if((rx_prologue->PCB.val & PCD_CMD_S_BLOCK_Msk) != PCD_CMD_S_BLOCK)
      {
                b_pr.valid = 5;//s_pcb err
                return b_pr;
      }
      if(rx_prologue->PCB.s_pcb.func == 3)
      {//wtx

      }
      else if(rx_prologue->PCB.s_pcb.func == 0)
      {//deselect
        b_pr.valid = 1;
        b_pr.prologue.PCB.s_pcb.blk_t = 3;
                b_pr.prologue.PCB.s_pcb.func = 0;
        b_pr.prologue.PCB.s_pcb.fixed0 = b_pr.prologue.PCB.s_pcb.fixed0_ = 0;
        b_pr.prologue.PCB.s_pcb.fixed1 = 1;
      }
      break;
    default:
      return b_pr;
  }
  return b_pr;
}

static void picc_t4t_rats_process(uint8_t *buf, uint16_t len)
{
    if(buf)
    {
        switch (buf[0])
        {
            case 0x50:
                picc_set_halt();
                break;
            case 0xe0:
                picc_cid_set(picc_run.rx_buf[1] & 0x0f);
                picc_run.rats.fsdi = au16FSD_CODE[((picc_run.rx_buf[1] >> 4) > 8)?8:(picc_run.rx_buf[1] >> 4)];
                memcpy(picc_run.tx_buf, &picc_conf.ats, sizeof(struct picc_ats));
                picc_run.tx_len = picc_conf.ats.TL;
                picc_write(picc_run.tx_buf, picc_run.tx_len);
                printf("PICC is Activated\r\n");
                picc_blk_num_set(1);
                picc_run_state(PICC_STATE_PPS);
                break;
            default:
                break;
        }
    }
}

static uint8_t picc_t4t_pps_process(uint8_t *buf, uint16_t len)
{
    uint8_t ret = 0;
    if(buf)
    {
        pps_t* pps = (pps_t*)buf;
        if((picc_check_cid(pps->PPSS.bitmap.cid)) &&\
            (pps->pps0 == 0x11))
        {
            picc_write(&pps->PPSS.val, 1);
            picc_set_rate(pps->pps1);
            ret = 1;
        }
        else
        {
            ret = 0;
        }
        picc_run_state(PICC_STATE_RECV_BLOCK);
    }
    return ret;
}

int parse_capdu(const uint8_t *apdu, uint16_t len, c_apdu_t *cmd) {
    if (len < 4) return -1;  // 基础头校验

     // 解析固定头
     cmd->cla = apdu[0];
     cmd->ins = apdu[1];
     cmd->p1 = apdu[2];
     cmd->p2 = apdu[3];
     uint8_t offset = 4;

     cmd->lc_type = 0;//无Lc
     // 处理Lc/Data部分
     if ((offset + 1) < len && apdu[offset] != 0x00) {  // 短Lc
             cmd->lc_type = 1;
             cmd->lc.short_lc = apdu[offset++];
             cmd->data = &apdu[offset];
             offset += cmd->lc.short_lc;
     } else if ((offset + 3) < len && apdu[offset] == 0x00) {  // 扩展Lc
             cmd->lc_type = 2;
             cmd->lc.ext_lc = (apdu[offset+1] << 8) | apdu[offset+2];
             offset += 3;
             cmd->data = &apdu[offset];
             offset += cmd->lc.ext_lc;
     }

     // 处理Le部分
     if (offset < len) {
        if((offset + 1) == len)
        {//短Le
            cmd->le_type = 1;
            cmd->le.short_le = apdu[offset++];
        }
        else if((offset + 2) == len)
        {
            if(cmd->lc_type != 2)return -3;
            cmd->le_type = 3;
            cmd->le.ext_le = (apdu[offset] << 8) | apdu[offset+1];
            offset += 2;
        }
        else if((offset + 3) == len)
        {
            if(cmd->lc_type != 1)return -4;
            if(apdu[offset] != 0)return -5;
            cmd->le_type = 2;
            cmd->le.ext_le = (apdu[offset+1] << 8) | apdu[offset+2];
            offset += 3;
        }
     }

     return (offset != len ? -5 : 0);

}

void build_web_uri(t4t_entity *tag, const char *url)
{

  ndef_uri_record *record = (ndef_uri_record*)&tag->ndef_data[tag->file_count * sizeof(ndef_uri_record)];
  record->header = 0xD1; // MB=1, ME=1, TNF=0x01
  record->type_len = 1;
  record->type = 'U';
  record->uri_prefix = 0x01; // "http://www."
  strncpy(record->uri, url, sizeof(record->uri));
  record->uri_len = 1 + strlen(url); // 前缀+URL长度
  record->ndef_len = (4 + (uint16_t)record->uri_len) >> 8 | (4 + (uint16_t)record->uri_len) << 8;
}

void init_t4t_entity(t4t_entity *tag)
{
    // 初始化CC文件
    tag->files[0] = (file_entry){
        .fid = 0xE103, .type = 2, .size = 15,
        .start_block = 0, .access_mode = 0x01
    };
    // 预置CC文件内容（参考NFC Forum T4T规范）
    uint8_t cc_data[] = {0x00, 0x0F, 0x20, 0x00, 0xFA, 0x00, 0xFA, 0x04, 0x06, 0xE1, 0x04, 0x7F, 0xFF, 0x00, 0x00};
    memcpy(tag->ndef_data, cc_data, sizeof(cc_data));
        tag->file_count++;

    // 初始化NDEF文件
    tag->files[1] = (file_entry){
        .fid = 0xE104, .type = 2, .size = sizeof(ndef_uri_record),
        .start_block = 1, .access_mode = 0x03
    };
    build_web_uri(tag, "megahuntmicro.com"); // 默认网址
    tag->file_count++;
}

file_entry * find_file(t4t_entity *tag, uint16_t fid)
{
    for(uint8_t i = 0;i < tag->file_count;i++)
    {
        if(tag->files[i].fid == fid)
            return &tag->files[i];
    }
    return NULL;
}

void handle_select(t4t_entity *tag, c_apdu_t *cmd, r_apdu_t *resp) {
    if (cmd->lc.ext_lc == 2)
        {
        tag->cur_file = find_file(tag, cmd->data[0] << 8 | cmd->data[1]);
        if (tag->cur_file) {
            resp->sw = 0x9000; // 成功状态码
        }
    } else if (cmd->lc.ext_lc == 7 && memcmp(cmd->data, "\xD2\x76\x00\x00\x85\x01\x01", 7) == 0) { // NDEF应用选择
        resp->sw = 0x9000; // 成功响应
    } else {
        resp->sw = 0x6A82;// 文件未找到
    }
}

void handle_read(t4t_entity *tag, c_apdu_t *cmd, r_apdu_t *resp) {
    uint16_t offset = (cmd->p1 << 8) | cmd->p2;

    if (offset + cmd->le.ext_le > tag->cur_file->size) {
        resp->sw = 0x6A84;// 地址越界
        return;
    }

    // 从存储块读取数据（支持跨块读取）
    resp->data = &tag->ndef_data[tag->cur_file->start_block * sizeof(ndef_uri_record) + offset];
        resp->len = cmd->le.ext_le;
    resp->sw = 0x9000; // 成功状态
}

static void picc_t4t_apdu_process(block_preprocess_t *prep, t4t_entity *tag)
{
    r_apdu_t rapdu = {0};
    c_apdu_t capdu = {0};
    if(prep->valid == 1)
    {
        switch (prep->prologue.PCB.val >> 6)
        {
            case 0://i block
                if(parse_capdu(prep->data, prep->data_len, &capdu))
                {
                    rapdu.sw = 0x6700;
                }
                else
                {
                    if(capdu.ins == 0xA4)
                    {
                        handle_select(tag, &capdu, &rapdu);
                    }
                    else if(capdu.ins == 0xB0)
                    {
                        handle_read(tag, &capdu, &rapdu);
                    }
                    else if(capdu.ins == 0xD0)
                    {

                    }
                    else
                    {
                        rapdu.sw = 0x6D00;
                    }
                    picc_t4t_send_i(&prep->prologue, &rapdu);
                }
                break;
            case 2:
                picc_t4t_send_r(&prep->prologue);
                break;
            case 3://s block
                if(prep->prologue.PCB.s_pcb.func == 0)
                {
                    picc_t4t_deselect(&prep->prologue);
                }
                break;
        }
        prep->valid = 0;
    }
}

static void picc_t4t_process(void)
{
    block_preprocess_t prep = {0};
    if(picc_run_state_check(PICC_STATE_RECV_BLOCK))
    {
        prep = picc_t4t_block_process(picc_run.rx_buf, picc_run.rx_len - 2);
    }
    else if(picc_run_state_check(PICC_STATE_ACTIVE))
    {
        picc_t4t_rats_process(picc_run.rx_buf, picc_run.rx_len);
    }
    else if(picc_run_state_check(PICC_STATE_PPS))
    {
        if(!picc_t4t_pps_process(picc_run.rx_buf, picc_run.rx_len))
            prep = picc_t4t_block_process(picc_run.rx_buf, picc_run.rx_len - 2);
    }
    picc_t4t_apdu_process(&prep, &t4t_tag);
}

void picc_14443_4_enable(uint8_t en)
{
  if(en)
  {
        hal_nfc_bit_set(10, 0x3A, 1, 1);
        hal_nfc_bit_clear(9, 0x3D, 0x80, 1);
        picc_conf.app = picc_t4t_process;
        init_t4t_entity(&t4t_tag);
  }
  else
  {
        hal_nfc_bit_clear(10, 0x3A, 1, 1);
        picc_conf.app = picc_t2t_process;
  }
}

//poll rx irq
void picc_rx_callback(uint32_t event)
{
  picc_run.rx_len = picc_get_rx_len();
  if(picc_run.rx_len)
  {
//      printf("PICC Recv data:%d\r\n",picc_run.rx_len);
    for(int i = 0; i < picc_run.rx_len; i++)
        picc_run.rx_buf[i] = hal_nfc_get_register(0, 0x09, 1);
//      for(int i = 0;i < picc_run.rx_len;i++)
//          printf("%02x ", picc_run.rx_buf[i]);
//      printf("\r\n");
  }
  else
  {
//    GPIO_SetBits(GPIOD, GPIO_Pin_5);
//    GPIO_ResetBits(GPIOD, GPIO_Pin_5);
    hal_nfc_set_register(0, 1, 0x8, 0);
    return;
  }
    if(!(event & (1 << ERR_EVENT)))
    {
        picc_conf.app();
    }
    else
    {
        picc_err_callback(event);
    }
}

static void picc_rx_irq(uint8_t en)
{
  if(en)
  {
    picc_event_register(RX_EVENT, picc_rx_callback);
    hal_nfc_bit_set(0, 0x02, PICC_RxIEn, 1);
  }
  else
  {
    hal_nfc_bit_clear(0, 0x02, PICC_RxIEn, 1);
    picc_event_unregister(RX_EVENT);
  }
}

void picc_init(void)
{
  picc_reset();
  hal_nfc_config(picc_configs, sizeof(picc_configs)/sizeof(hal_nfc_regval_t));

  picc_uid_set(picc_conf.uid, picc_conf.coll_level == 2?7:4);
  picc_set_atqa_hbyte(picc_conf.atqa >> 8);
  picc_set_atqa_lbyte(picc_conf.atqa & 0x1F);
  picc_14443_4_enable(picc_conf.enable_14443_4);
  picc_field_in_irq(1);
  picc_field_out_irq(1);
  picc_active_irq(1);
  picc_rx_irq(1);
//    NVIC_InitTypeDef NVIC_InitStructure;
//    NVIC_SetPriorityGrouping(NVIC_PriorityGroup_3);
//    NVIC_InitStructure.NVIC_IRQChannel = EXIT_IRQ_NUM;
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//    NVIC_Init(&NVIC_InitStructure);

//  mh1612s_card_emu_optimize_init();
}
__HIGH_CODE
void picc_event_process(void)
{
  if(INT_PIN)
  {
    uint32_t event = picc_get_event();
    for(intc_event_e e = TIMER_EVENT; e < EVENT_NUM; e++)
    {
      if(event & (1 << e))
      {
        if(picc_conf.event[e])
          picc_conf.event[e](event);
      }
    }
  }
}

void update_t2t_mem(uint8_t *data, uint16_t data_len){
//    memset(&t2t_mem[4][0], 0, 512);
//    memcpy(&t2t_mem[4][0], data, data_len);
    t2t_mem[5][2] = 4 + data_len ;
    t2t_mem[5][3] = 0x91;
    t2t_mem[6][1] = data_len - 0x20 ;
    memset(&t2t_mem[7][0], 0, 512);
    memcpy(&t2t_mem[7][0], data, data_len);

    save_eeprom_picc_data(&t2t_mem[0][0], 248);
}

void sync_eeprom_t2t_mem(void){
    uint8_t eeprom_data[512] = {0};
    uint16_t len = 0;

    if(get_eeprom_picc_data( eeprom_data, &len)){
       // dk_log_hex("eeprom_data", eeprom_data, len);
        memcpy(&t2t_mem[0][0], eeprom_data, len);
    }
}

void intc_irq_handler(void)
{
  if(GPIO_ReadPortPin(READER_IRQ_PORT, READER_IRQ_Pin))
  {
   // mh1612s_card_emu_optimize_irq_callback(opt_hw, picc_run.state, 500);
  }

  do
  {
//    EXTI_ClearITPendingBit(EXIT_LINE_NUM);
//    NVIC_ClearPendingIRQ(EXIT_IRQ_NUM);
    uint32_t event = picc_get_event();
    for(intc_event_e e = TIMER_EVENT; e < EVENT_NUM; e++)
    {
      if(event & (1 << e))
      {
        if(picc_conf.event[e])
          picc_conf.event[e](event);
      }
    }
  } while(hal_nfc_bit_check(0, 0x7, BIT4, 0));

}

